package cc.yihy.web.shiro.realm;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

/**
 * 
 * @ClassName:DefAuthorizingRealm.java
 * @Description: 标签and or not 简单支持   <shiro:hasPermission name="showcase:tree:create or showcase:tree:update or showcase:tree:delete">
 * @Author: yihy
 * @Since: 2016年9月18日
 * @Version: 1.0
 */
public abstract class DefAuthorizingRealm extends AuthorizingRealm {

	   private static final String OR_OPERATOR = " or ";
	    private static final String AND_OPERATOR = " and ";
	    private static final String NOT_OPERATOR = "not ";
	    /**
	     * 支持or and not 关键词  不支持and or混用
	     * @param principals
	     * @param permission
	     * @return
	     */
	    @Override
	    public boolean isPermitted(PrincipalCollection principals, String permission) {
	        if(permission.contains(OR_OPERATOR)) {
	            String[] permissions = permission.split(OR_OPERATOR);
	            for(String orPermission : permissions) {
	                if(isPermittedWithNotOperator(principals, orPermission)) {
	                    return true;
	                }
	            }
	            return false;
	        } else if(permission.contains(AND_OPERATOR)) {
	            String[] permissions = permission.split(AND_OPERATOR);
	            for(String orPermission : permissions) {
	                if(!isPermittedWithNotOperator(principals, orPermission)) {
	                    return false;
	                }
	            }
	            return true;
	        } else {
	            return isPermittedWithNotOperator(principals, permission);
	        }
	    }

	    private boolean isPermittedWithNotOperator(PrincipalCollection principals, String permission) {
	        if(permission.startsWith(NOT_OPERATOR)) {
	            return !super.isPermitted(principals, permission.substring(NOT_OPERATOR.length()));
	        } else {
	            return super.isPermitted(principals, permission);
	        }
	    }

		@Override
		protected AuthorizationInfo doGetAuthorizationInfo(
				PrincipalCollection principals) {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		protected AuthenticationInfo doGetAuthenticationInfo(
				AuthenticationToken token) throws AuthenticationException {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public void onLogout(PrincipalCollection principals) {
			
			clearCached();
			super.onLogout(principals);
		} 
	    
		public void clearCached() {
			PrincipalCollection principals = SecurityUtils.getSubject()
					.getPrincipals();
			
			this.clearCache(principals);
			this.clearCachedAuthenticationInfo(principals);
			this.clearCachedAuthorizationInfo(principals);
			super.clearCache(principals);
		}
	    
}

